#ifndef _SRC_FLOG_H
#define _SRC_FLOG_H
#include <string>
#include <sstream>
#include <iostream>
#include <functional>

using LogCbk = std::function<void(const std::string&)>;

class DefaultLogHandler{
public:
    void operator()(const std::string& value){
        std::cout<<value;
    }
};

enum LogLevel{
    INFO,
    WARN,
    ERROR
};

class LogHelper{
public:
    LogHelper(LogLevel level,const char* file,int lineno,LogCbk cbk= DefaultLogHandler()):level_(level),filename_(file),lineno_(lineno),cbk_(cbk){

    }

    ~LogHelper()
    {
        ss_ <<std::endl;
        cbk_(ss_.str());
    }

    template<typename T>
    std::ostream& operator<<(T value){
        std::string level;
        switch (level_){
            case INFO:
            level = "INFO";
            break;
            case WARN:
            level = "WARN";
            break;
            case ERROR:
            level = "ERROR";
            break;
        }
        ss_ << level <<" "<<time(NULL)<<","<<filename_<<":"<<lineno_<<"  "<<value;
        return ss_;
    }

private:
    LogLevel level_;
    std::string filename_;
    int lineno_;
    std::stringstream ss_;
    LogCbk cbk_;
};

#define _LOG(cbk,level) \
    LogHelper(level,__FILE__,__LINE__,cbk) 

#endif